package com.vlyman.rsa;

import com.vlyman.utils.ApplicationYaml;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.*;

import static com.vlyman.consts.KeyConsts.RSA_ALGORITHM;

/**
 * 类描述：
 *  rsa公钥私钥生成类
 * @author chenjs
 * @date 2019/1/11 12:28
 **/
@Slf4j
public class RsaKeyCreator {

    public static final String RSA_KEY_STORE_PATH = ApplicationYaml.getValue("rsa.path");
    public static final String RSA_KEY_FILE = RSA_KEY_STORE_PATH + "/" + ApplicationYaml.getValue("rsa.key-file");
    public static final String RSA_KEY_SOURCE_FILE = RSA_KEY_STORE_PATH + "/" + ApplicationYaml.getValue("rsa.key-source-file");

    /**
     * 方法描述：
     *   生成公钥和私钥
     *  @author chenjs
     *  @param keySize 密钥长度
     *  @date 2019/1/11 12:50
     */
    public static void createKeyPairs(int keySize) throws Exception{
        // 为RSA算法创建一个KeyPairGenerator对象
        KeyPairGenerator keyPairGenerator;
        try{
            keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM, new BouncyCastleProvider());
        } catch (NoSuchAlgorithmException e){
            throw new IllegalArgumentException("无此加密算法-->[" + RSA_ALGORITHM + "]");
        }
        // 初始化KeyPairGenerator对象,密钥长度
        keyPairGenerator.initialize(keySize, new SecureRandom());
        //生成密匙对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //得到公钥
        Key publicKey = keyPair.getPublic();
        System.out.println(publicKey);
        //得到私钥
        Key privateKey = keyPair.getPrivate();
        System.out.println(privateKey);
        String sourceStr = String.valueOf(publicKey) + String.valueOf(privateKey);
        System.out.println(sourceStr);
        saveKeyPair(sourceStr, RSA_KEY_SOURCE_FILE);
        saveKeyPair(keyPair, RSA_KEY_FILE);
    }

    /**
     * 方法描述：
     *   将对象保存到本地文件
     *  @author chenjs
     *  @param writeObj 待输出对象
     *  @date 2019/1/12 10:54
     */
    public static void saveKeyPair(Object writeObj, String path) {
        try {
            @Cleanup
            FileOutputStream fos = new FileOutputStream(path);
            @Cleanup
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(writeObj);
            oos.close();
            fos.close();
        } catch (Exception e) {
            log.error("将对象保存到本地文件失败！path="+path, e);
        }
    }

    /**
     * 方法描述：
     *   从本地文件获取RSA密钥对
     *  @author chenjs
     *  @return RSA密钥对
     *  @date 2019/1/12 13:52
     */
    public static KeyPair getKeyPair() throws Exception {
        FileInputStream fis = new FileInputStream(RSA_KEY_FILE);
        ObjectInputStream oos = new ObjectInputStream(fis);
        KeyPair kp = (KeyPair) oos.readObject();
        oos.close();
        fis.close();
        return kp;
    }


    public static void main(String[] args) {
        try {
            //createKeyPairs(1024);
            System.out.println(RSA_KEY_STORE_PATH);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
